# Handles Zeemote remote device input on PC, control mouse with remote
# Copyright (C) 2009  Aleksandar Kordic

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA


import sys
import bluetooth 
import struct 
import time 
from traceback import print_exc
from bluetooth import BluetoothSocket 
from au3_mouse import moveMouse, mouseButtons, moveMousePrecise2
from threading import Thread

class RemoteController:
	KEY_STARTER = '\x08'
	KEY_EMPTY = '\xFE'
	STICK_STARTER = '\x05'
	REMOTE_CONTROL_PORT = 1

	def __init__(self):
		self.remote = None #'00:1C:4D:00:53:71'
		self.x, self.y = 0.0, 0.0
		
	def find_mac_address(self):
		remote = None 
		while 1:
			try:
				devices = bluetooth.discover_devices()
				for device in devices:
					name = bluetooth.lookup_name(device, timeout=6)
					print 'found device:', name
					if name == u'Zeemote JS1':
						print 'found remote control device:', device
						remote = device 
						break 
				else:
					print ' - no remote in scope !'
				if remote: return remote 
			
			except IOError, ex:
				print ex 
			time.sleep(0.4)
	
	def connect_to_address(self, addr):
		s = BluetoothSocket(bluetooth.RFCOMM)
		#for i in range(0, 30):
		while 1:
			try:
				s.connect((self.remote, self.REMOTE_CONTROL_PORT))
				#print 'connected on %d port' % i
				print 'connected ..'
				break
			except IOError, ex:
				print ex
			except:
				print 'failure on port:', self.REMOTE_CONTROL_PORT
				print_exc()
			time.sleep(0.3)
		return s 
	
	def run(self):
		self.remote = self.find_mac_address()
		self.s = self.connect_to_address(self.remote)
		
		print 'dump buffered chunk ..', self.s.recv(1000).encode('hex')
		time.sleep(0.2)
		print 'dump buffered chunk ..', self.s.recv(1000).encode('hex')

		self._worker_running = True 
		t = Thread(target=self.worker)
		t.setDaemon(True)
		t.start()

		while 1:
			time.sleep(0.05)
			## repeat mouse move command
			if self.x != 0 or self.y != 0: moveMousePrecise2(self.x, self.y)

	def worker(self):
		while self._worker_running:
			try:
				b = self.s.recv(1)
			except:
				print_exc()
				sys.exit(0)
			else:
				if b == self.KEY_STARTER:
					data = self.s.recv(8)
					buttons = [ ord(e) for e in data[2:] if e != self.KEY_EMPTY ]
					mouseButtons(buttons)
					#print buttons 
				elif b == self.STICK_STARTER:
					self.x, self.y = [ c/128.0 for c in struct.unpack('<bb', self.s.recv(5)[-2:]) ]
					#moveMouse(self.x, self.y)
					#print 'move', self.x, self.y

if __name__ == '__main__':
	rc = RemoteController()
	rc.run()




